// https://dvajs.com/api/#reducers
// dva配置启用 - 使用model默认会启用
import { Reducer, Effect, Subscription } from 'umi';
import {getRemoteList, editRecord, deleteRecord, addRecord} from './service';
import {SingleUserType} from './data.d'

export interface UserState {
  data: SingleUserType[];
  meta: {
    total: number;
    per_page: number;
    page: number;
  }
}

interface UserModelType {
  namespace: 'users';
  state: UserState;
  reducers: {
    getList: Reducer<UserState>;
  };
  effects: {
    getRemote: Effect;
    edit: Effect;
    delete: Effect;
    add: Effect;
  };
  subscriptions: {
    setup: Subscription;
  };
}

const UserModel: UserModelType = {
  // Model唯一的标识(固定)
  namespace: 'users',

  // 仓库的初始值(固定)
  state: {
    data: [],
    meta: {
      total: 0,
      per_page: 5,
      page: 1
    }
  },

  // 同步
  // reducers里所有的函数参数是(state, action) === (state, {type, payload})
  // state是过去的数据
  reducers: {
    getList(state, action) {
      return action.payload;
    }
  },

  // 异步，因为是异步，所以都需要加*号(generate函数)
  // 参数是(action, effects) === ({type, payload}, effects)
  // effects === (put, call)
  effects: {
    *getRemote(action, {put, call}) {
      // 通过put方法给reducers
      // yield put();

      const data = yield call(getRemoteList);
      if (data) {
        yield put({
          type: 'getList',
          payload: data
        });
      }
    },
    // 对象里的展开，必须要把字段名写出来
    *edit({payload: {id, values}}, {put, call}) {
      // 第一个参数是方法，第二个参数是需要传递的对象
      const data = yield call(editRecord, {id, values});
      if (data) {
        yield put({
          type: 'getRemote'
        });
      }
    },
    *delete({payload}, {put, call}) {
      // 第一个参数是方法，第二个参数是需要传递的对象
      const data = yield call(deleteRecord, payload);
      if (data) {
        yield put({
          type: 'getRemote'
        });
      }
    },
    *add({payload}, {put, call}) {
      yield call(addRecord, payload);

      yield put({
        type: 'getRemote'
      });
    }
  },

  // 订阅
  subscriptions: {
    setup({ dispatch, history }) {
      // dispatch后面的参数一定是action
      // action是对象，有type(函数名字)
      // payload: 除了type，需要传递的所有数据装到payload
      // dispatch(action);

      return history.listen(({pathname}) => {
        if (pathname === '/users') {
          // 触发getRemote
          dispatch({
            type: 'getRemote',
          });
        }
      });
    }
  }
};

export default UserModel;
